//
// Created by yonghu0 on 25-10-19.
//

#include "UserList.h"

#include <netdb.h>

#include "MongoDataBase.h"
#include "RedisDataBase.h"
#include "snowflake.hpp"

using snowflake_t = snowflake<1534832906275L, std::mutex>;
snowflake_t uuid_token;

UserList::UserList()
{
}

UserList::~UserList()
{
}

UserList *UserList::GetInstance()
{
    static UserList userlist;
    return &userlist;
}

Json::Value UserList::RegisterUser(Json::Value registerjson)
{
    Json::Value resjson = MoDB::GetInstance()->RegisterUser(registerjson);
    if (resjson["Result"].asString() == "Success")
    {
        int64_t id = resjson["_id"].asInt64();
        m_user_authority_map[id] = 3;
    }

    for (auto elem: m_user_authority_map)
    {
        std::cout << "[" << elem.first << ":" << elem.second << "]" << std::endl;
    }
    return resjson;
}

Json::Value UserList::LoginUser(Json::Value loginjson)
{
    Json::Value resjson = MoDB::GetInstance()->LoginUser(loginjson);
    if (resjson["Result"].asString() == "Success")
    {
        uuid_token.init(1, 1);

        int64_t token = uuid_token.nextid();

        ReDB::GetInstance()->SetToken(std::to_string(token), resjson["Info"]["_id"].asString());

        resjson["Info"]["Token"] = std::to_string(token);
    }
    return resjson;
}

Json::Value UserList::SelectUserInfo(Json::Value selectjson)
{
    return MoDB::GetInstance()->SelectUserInfo(selectjson);
}

Json::Value UserList::UpdateUser(Json::Value updatejson)
{
    return MoDB::GetInstance()->UpdateUser(updatejson);
}

Json::Value UserList::GetUserUpdateInfo(Json::Value getjson)
{
    return MoDB::GetInstance()->GetUserUpdateInfo(getjson);
}

Json::Value UserList::GetUserlistInfo(Json::Value getjson)
{
    return MoDB::GetInstance()->GetUserlistInfo(getjson);
}

Json::Value UserList::DeleteUser(Json::Value deletejson)
{
    Json::Value resjson = MoDB::GetInstance()->DeleteUser(deletejson);
    if (resjson["Reuest"].asString() == "Success")
    {
        int64_t id = stoll(deletejson["UserId"].asString());
        m_user_authority_map.erase(id);
    }
    return resjson;
}

Json::Value UserList::RankUser(Json::Value rankjson)
{
    return MoDB::GetInstance()->RankUser(rankjson);
}

Json::Value UserList::TokenLoginUser(Json::Value loginjson)
{
    std::string token = loginjson["Token"].asString();

    std::string userid = ReDB::GetInstance()->GetUserIdByToken(token);

    loginjson["UserId"] = userid;

    return MoDB::GetInstance()->TokenLoginUser(loginjson);
}

bool UserList::UpdateUserProblemInfo(Json::Value updatejson)
{
    return MoDB::GetInstance()->UpdateUserProblemInfo(updatejson);
}

bool UserList::InitUserAuthority()
{
    Json::Value json = MoDB::GetInstance()->SelectUserAuthority();

    if (json["Result"].asString() == "Fail")
        return false;

    for (int i = 0; i < json["ArrayInfo"].size(); i++)
    {
        int64_t userid = json["ArrayInfo"][i]["_id"].asInt64();
        int authority = json["ArrayInfo"][i]["Authority"].asInt();
        m_user_authority_map[userid] = authority;
    }

    // for (auto elem: m_user_authority_map)
    // {
    //     std::cout << "[" << elem.first << ":" << elem.second << "]" << std::endl;
    // }
    return true;
}

void TokenToVerifyId(Json::Value &json)
{
    if (!json["Token"].isNull())
    {
        json["VerifyId"] = ReDB::GetInstance()->GetUserIdByToken(json["Token"].asString());
    }
}

int UserList::GetUserAuthority(Json::Value &json)
{
    /*
        用户权限
        1：游客
        3：普通用户
        5：管理员
    */
    //游客
    if (json["VerifyId"].isNull() || json["VerifyId"].asString() == "0")
        return VISITOR;

    try
    {
        int64_t id = stoll(json["VerifyId"].asString());
        if (m_user_authority_map.find(id) != m_user_authority_map.end())
            return m_user_authority_map[id];
        else
            return VISITOR;
    } catch (std::exception &e)
    {
        return VISITOR;
    }
}

//普通用户及以上
bool UserList::IsOrdinaryUser(Json::Value &json)
{
    TokenToVerifyId(json);
    if (GetUserAuthority(json) >= ORDINARY_USER)
        return true;
    else
        return false;
}

// 是否是作者本人或以上
bool UserList::IsAuthor(Json::Value &json)
{
    TokenToVerifyId(json);
    int authority = GetUserAuthority(json);

    if (authority < ORDINARY_USER)
        return false;

    if (authority >= ADMINISTRATOR)
        return true;

    try
    {
        int64_t verifyid = stoll(json["VerifyId"].asString());
        int64_t userid = stoll(json["UserId"].asString());

        if (verifyid == userid)
            return true;
        else
            return false;
    } catch (const std::exception &e)
    {
        return false;
    }
}

// 是否是管理员或以上
bool UserList::IsAdministrator(Json::Value &json)
{
    TokenToVerifyId(json);
    if (GetUserAuthority(json) >= ADMINISTRATOR)
        return true;
    else
        return false;
}
